﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using OnlineEducation.Controllers;
using OnlineEducation.Data;
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using OnlineEducation.Extensions;
using System.Collections.Generic;
using OnlineEducation.Data.Entities;
using OnlineEducation.Models.JQueryTable;
using OnlineEducation.Helpers.JQueryTable;
using System.IO;
using Microsoft.AspNetCore.Hosting;
using OnlineEducation.Helpers;
using OnlineEducation.Constants;
using OnlineEducation.Models.CourseViewModels;
using Microsoft.AspNetCore.Connections.Features;
using AutoMapper;

namespace OnlineEducation.Areas.Controllers
{
    /// <summary>
    /// Course management, you can query, add, edit, delete products
    /// </summary>
    [Area("Course")]
    [Route("[controller]")]
    [Authorize(Roles = "SuperAdmin,Teacher")]
    public class CourseController : BaseController
    {
        private readonly ILogger _logger;
        private readonly ApplicationDbContext _context;
        private readonly IWebHostEnvironment _env;
        private readonly IMapper _mapper;

 

        public CourseController(ApplicationDbContext context, ILogger<BookingController> logger, IWebHostEnvironment env, IMapper mapper)
        {
            _context = context;
            _logger = logger;
            _env = env;
            _mapper = mapper;

        }
        /// <summary>
        /// Get all products
        /// </summary>
        /// <returns></returns>
        [HttpGet("Index")]
        public async Task<IActionResult> Index()
        {
            var model = new CourseViewModel();

            var teacherId =  User.GetUserID() ;

            var courserInfo = await _context.Courses.Where(r => r.TeacherId == teacherId).ToListAsync();
            model.TotalAllCourseCount = courserInfo.Count;
            model.TotalAllPublishedCourseCount = courserInfo.Where(r => r.Status == 1).Count();
            model.TotalAllUnPublishedCourseCount = courserInfo.Where(r => r.Status == 0).Count();
            model.TotalAllClosedCourseCount = courserInfo.Where(r => r.Status == 0).Count();


            return View(model);
        }


        /// <summary>
        /// Gets all courses.
        /// </summary>
        /// <param name="param">The parameter.</param>
        /// <returns></returns>
        [HttpPost("GetAll")]
        public IActionResult GetAll(DTParameters param)
        {
            var teacherId =  User.GetUserID() ;

            var query = _context.Courses.Where(r => r.TeacherId == teacherId).Include(n => n.Lessons).AsQueryable();

            if (param.Search != null && !string.IsNullOrEmpty(param.Search.Value))
            {
                query = query.Where(n => n.Description.Contains(param.Search.Value) || n.Title.Contains(param.Search.Value) || n.SubTitle.Contains(param.Search.Value));

            }


            var codeMgt = new CodeManager(_context);

            var newQuery = new SortHelper<Course>().Apply(query, param);

            var items = newQuery.Skip(param.Start).Take(param.Length).ToArray();

            foreach (var item in items)
            {
                item.Subject = codeMgt.GetValue(item.SubjectCode);

                item.PlanQty = _context.TeachingPlans.Count(n => n.CourseId == item.Id && n.Status == 1);
            }

            var count = newQuery.Count();

            return Json(new DTResult<Course>
            {
                draw = param.Draw,
                data = items,
                recordsFiltered = count,
                recordsTotal = count
            });
        }


        /// <summary>
        /// Gets the lessons.
        /// </summary>
        /// <param name="param">The parameter.</param>
        /// <returns></returns>
        [HttpPost("Lessons")]
        public IActionResult GetLessons(DTParameters param)
        {
            //var temp_data = HttpContext.Session.Get<CourseData>(TEMP_COURSE_DATA_KEY);

            //if (temp_data == null)
            //{
            //    temp_data = new CourseData();
            //}
            int courseId;

            if (param.AdditionalValues.Any())
            {
                courseId = int.Parse(param.AdditionalValues.First());

                var lesson = _context.Lessons.Where(n => n.CourseId == courseId);

                int count = lesson.Count();


                return Json(new DTResult<OnlineEducation.Data.Entities.Lesson>
                {
                    draw = param.Draw,
                    data = lesson,
                    recordsFiltered = count,
                    recordsTotal = count
                });
            }
            else
            {
                return Json(new DTResult<OnlineEducation.Data.Entities.Lesson>
                {
                    draw = param.Draw,
                    data = new List<Lesson>(),
                    recordsFiltered = 0,
                    recordsTotal = 0
                });
            }



            //var newQuery = new SortHelper<Data.Entities.Lesson>().Apply(temp_data.Lessons.AsQueryable(), param);

            //var items = newQuery.Skip(param.Start).Take(param.Length).ToArray();

            //var count = newQuery.Count();

            //return Json(new DTResult<OnlineEducation.Data.Entities.Lesson>
            //{
            //    draw = param.Draw,
            //    data = items,
            //    recordsFiltered = count,
            //    recordsTotal = count
            //});

        }
        /// <summary>
        /// add a course.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns></returns>
        [HttpGet("Add")]
        public IActionResult Add(int? id)
        {
            var subjects = _context.Codes.Where(n => n.Category == Constants.Code.Subject).ToList();

            //if(subjects==null || subjects.Count == 0)
            //{
            //    return BadRequest("尚未添加科目,请在科目管理添加科目");
            //}
            ViewBag.Subjects = subjects;

            if (id.HasValue && id.Value > 0)
            {
                var course = _context.Courses.Find(id);

                return View("AddCourse", course);
            }
            else
            {
                return View("AddCourse", new Course { TeacherId = User.GetUserID() });
            }

        }

        /// <summary>
        /// Adds the specified data.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        [HttpPost("Add")]
        public async Task<IActionResult> Add(Course data)
        {

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            try
            {
                var files = Request.Form.Files;

                var guid = Guid.NewGuid().ToString();

                if (files != null && files.Any() && files[0] != null && files[0].Length > 0)
                {
                    await SaveFiles(data, files);

                }

                if (data.Id > 0)
                {
                    var course = _context.Courses.Find(data.Id);

                    _mapper.Map(data, course);

                    _context.Update(course);

                    await _context.SaveChangesAsync();

                    return Json(new { success = true, message = "更新数据成功.", data = data.Id });
                }
                else
                {
                    _context.Add(data);

                    await _context.SaveChangesAsync();

                    return Json(new { success = true, message = "新增数据成功.", data = data.Id });
                }



            }
            catch (Exception ex)
            {
                return Json(new { success = false, message = ex.Message });
            }

            async Task SaveFiles(Course data, IFormFileCollection files)
            {
                var extension = Path.GetExtension(files[0].FileName);

                var filenamewithoutExt = Path.GetFileNameWithoutExtension(files[0].FileName);

                string fileName = filenamewithoutExt + DateTime.Now.ToString("MMddHHmmssfff") + extension;

                using (FileStream fs = System.IO.File.Create(Path.Combine(_env.WebRootPath, "upload", "cover", fileName)))//创建文件流
                {
                    await files[0].CopyToAsync(fs);

                    await fs.FlushAsync();
                }

                data.CoverPictureURL = "/upload/cover/" + fileName;
            }
        }

        /// <summary>
        /// Gets the lesson.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns></returns>
        [HttpGet("Lesson/{id?}")]
        public async Task<IActionResult> GetLesson(int? id)
        {
            if (!id.HasValue)
            {
                return BadRequest("id为空");
            }

            var lesson = await _context.Lessons.Where(n => n.Id == id.Value).FirstOrDefaultAsync();

            return View("ViewLesson", lesson ?? new Lesson());

        }

        /// <summary>
        /// Adds the lesson.
        /// </summary>
        /// <param name="courseId">The course identifier.</param>
        /// <returns></returns>
        [HttpGet("Lesson/Add")]
        public IActionResult AddLesson(int? courseId)
        {
            if (!courseId.HasValue)
            {
                return BadRequest("尚未添加课程，请先添加课程");
            }
            var lesson = new Lesson
            {
                CourseId = courseId.Value,
                Duration = 40
            };
            var courseData = _context.Courses.Include(r => r.Lessons).Where(r => r.Id == courseId.Value).FirstOrDefault();

            if (courseData.Lessons.Any())
            {

                lesson.Sequence = courseData.Lessons.Max(n => n.Sequence) + 1;
            }
            else
            {
                lesson.Sequence = 1;
            }


            return View("AddLesson", lesson);
        }
        /// <summary>
        /// Adds the lesson.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        [HttpPost("Lesson/Add")]
        public async Task<IActionResult> AddLesson(Lesson data)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            try
            {
                var seq = data.Sequence;

                var courseId = data.CourseId;

                var existSameSeq = _context.Lessons.Where(n => n.CourseId == courseId && n.Sequence == seq).Any();

                if (existSameSeq)
                {
                    return BadRequest("相同序号已经存在,请更改.");
                }


                var files = Request.Form.Files;

                if (files != null && files.Any() && files[0] != null && files[0].Length > 0)
                {
                    await SaveFiles(data, files);

                }

                data.Status = 1;

                _context.Add(data);

                _context.SaveChanges();

                return Json(new { success = true, message = "新增数据成功." });

            }
            catch (Exception ex)
            {
                return Json(new { success = false, message = ex.Message });
            }

            async Task SaveFiles(Lesson data, IFormFileCollection files)
            {
                var extension = Path.GetExtension(files[0].FileName);

                var filenamewithoutExt = Path.GetFileNameWithoutExtension(files[0].FileName);

                string fileName = filenamewithoutExt + DateTime.Now.ToString("MMddHHmmssfff") + extension;

                using (FileStream fs = System.IO.File.Create(Path.Combine(_env.WebRootPath, "upload", "course", fileName)))//创建文件流
                {
                    await files[0].CopyToAsync(fs);

                    await fs.FlushAsync();
                }

                data.MaterialURLs = "/upload/course/" + fileName;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("Lesson/Edit/{id?}")]
        public IActionResult EditLesson(int? id)
        {
            if (id.HasValue)
            {
                var lesson = _context.Lessons.Find(id.Value);

                if (lesson == null)
                {
                    return NotFound("Lesson已经失效");
                }

                return View("EditLesson", lesson);
            }
            else
            {
                return NotFound("Lesson已经失效");

            }
        }
        /// <summary>
        /// Edits the lesson.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        [HttpPost("Lesson/Edit/{id?}")]
        public async Task<IActionResult> EditLesson(int? id, Lesson data)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            if (!id.HasValue)
            {
                return NotFound("Lesson已经失效");
            }
            try
            {
                var files = Request.Form.Files;

                if (files != null && files.Any() && files[0] != null && files[0].Length > 0)
                {
                    await SaveFiles(data, files);

                }

                var lessson = _context.Lessons.Find(id.Value);

                if (lessson == null)
                {
                    return NotFound("Lesson已经失效");
                }
                else
                {

                    _mapper.Map(data, lessson);

                    _context.Update(lessson);

                    await _context.SaveChangesAsync();

                }


                return Json(new { success = true, message = "修改数据成功." });

            }
            catch (Exception ex)
            {
                return Json(new { success = false, message = ex.Message });
            }

            async Task SaveFiles(Lesson data, IFormFileCollection files)
            {
                var extension = Path.GetExtension(files[0].FileName);

                var filenamewithoutExt = Path.GetFileNameWithoutExtension(files[0].FileName);

                string fileName = filenamewithoutExt + DateTime.Now.ToString("MMddHHmmssfff") + extension;

                using (FileStream fs = System.IO.File.Create(Path.Combine(_env.WebRootPath, "upload", "course", fileName)))//创建文件流
                {
                    await files[0].CopyToAsync(fs);

                    await fs.FlushAsync();
                }

                data.MaterialURLs = "/upload/course/" + fileName;
            }
        }
        /// <summary>
        /// Deletes the lesson.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns></returns>
        [HttpPost("Lesson/Delete/{id?}")]
        public IActionResult DeleteLesson(int? id)
        {
            try
            {
                if (!id.HasValue)
                {
                    return BadRequest("id为空");
                }
                var lessoninfo = _context.Lessons.Find(id);
                if (lessoninfo != null)
                {
                    _context.Lessons.Remove(lessoninfo);
                    _context.SaveChanges();
                }
                return Json(new { success = true, message = "删除数据成功." });
            }
            catch (Exception ex)
            {
                return Json(new
                {
                    success = false,
                    message = ex.Message
                });
            }

        }

        /// <summary>
        /// edit a course.
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("Edit/{id?}")]
        public async Task<IActionResult> Edit(int? id)
        {
            if (!id.HasValue)
            {
                return BadRequest("id为空");
            }

            var subjects = _context.Codes.Where(n => n.Category == Constants.Code.Subject).ToList();

            ViewBag.Subjects = subjects;

            ViewBag.isEdit = 1;

            var course = await _context.Courses.Include(n => n.Lessons).Where(n => n.Id == id.Value).FirstOrDefaultAsync();

            if (course != null)
            {

                return View("EditCourse", course);
            }
            else
            {
                return BadRequest("课程不存在");
            }

        }

        /// <summary>
        /// Edits the specified data.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        [HttpPost("Edit")]
        public async Task<IActionResult> Edit(Course data)
        {

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            try
            {
                var files = Request.Form.Files;

                var guid = Guid.NewGuid().ToString();

                if (files != null && files.Any() && files[0] != null && files[0].Length > 0)
                {
                    await SaveFiles(data, files);

                }

                if (data.Id > 0)
                {
                    var course = _context.Courses.Find(data.Id);

                    _mapper.Map(data, course);

                    _context.Update(course);

                    await _context.SaveChangesAsync();

                    return Json(new { success = true, message = "更新数据成功.", data = data.Id });
                }
                else
                {
                    return BadRequest("课程不存在");
                }



            }
            catch (Exception ex)
            {
                return Json(new { success = false, message = ex.Message });
            }

            async Task SaveFiles(Course data, IFormFileCollection files)
            {
                var extension = Path.GetExtension(files[0].FileName);

                var filenamewithoutExt = Path.GetFileNameWithoutExtension(files[0].FileName);

                string fileName = filenamewithoutExt + DateTime.Now.ToString("MMddHHmmssfff") + extension;

                using (FileStream fs = System.IO.File.Create(Path.Combine(_env.WebRootPath, "upload", "cover", fileName)))//创建文件流
                {
                    await files[0].CopyToAsync(fs);

                    await fs.FlushAsync();
                }

                data.CoverPictureURL = "/upload/cover/" + fileName;
            }
        }

        [HttpPost("Publish/{id}")]
        public async Task<IActionResult> Publish(int? id)
        {
            if (!id.HasValue)
            {
                return BadRequest("id为空");
            }
            var courserInfo = await _context.Courses.FindAsync(id.Value);

            if (courserInfo == null)
            {
                return NotFound("未找到课程");
            }

            courserInfo.Status = 1;

            _context.Update(courserInfo);

            await _context.SaveChangesAsync();

            return Json(new { success = true, message = "发布课程成功." });
        }

        [HttpPost("Unpublish/{id?}")]
        public async Task<IActionResult> Unpublish(int? id)
        {
            if (!id.HasValue)
            {
                return BadRequest("id为空");
            }

            try
            {
                var course = await _context.Courses.FindAsync(id.Value);

                if (course == null)
                {
                    return NotFound("未找到课程");
                }
                if (course.Status == 1)
                {
                    bool isExistPublishPlan = _context.TeachingPlans.Any(n => n.CourseId == course.Id && n.Status == 1);

                    if (isExistPublishPlan)
                    {
                        return BadRequest("目前有发布的教学计划关联到这个课程，不能变更状态");
                    }

                    course.Status = 0;
                }
                else
                {
                    course.Status = 1;
                }

                _context.Update(course);

                await _context.SaveChangesAsync();

                return Json(new { success = true, message = "状态变更成功." });
            }
            catch (Exception ex)
            {

                return Json(new { success = false, message = ex.Message });
            }


        }

        /// <summary>
        /// Remove a course
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost("Delete/{id?}")]
        public async Task<IActionResult> Delete(int? id)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            try
            {
                var service = await _context.Courses.SingleOrDefaultAsync(m => m.Id == id);

                if (service == null)
                {
                    return NotFound();
                }

                _context.Courses.Remove(service);
                await _context.SaveChangesAsync();

                return Json(new { success = true, message = "删除数据成功." });
            }
            catch (Exception ex)
            {

                return Json(new { success = false, message = ex.Message });
            }


        }

        /// <summary>
        /// Views the specified identifier.
        /// </summary>
        /// <param name="id">The identifier.</param>
        /// <returns></returns>
        [HttpGet("View/{id?}")]
        public async Task<IActionResult> View(int? id)
        {
            if (!id.HasValue)
            {
                return BadRequest("id为空");
            }

            var subjects = _context.Codes.Where(n => n.Category == Constants.Code.Subject).ToList();

            ViewBag.Subjects = subjects;

            var course = await _context.Courses.Include(n => n.Lessons).Where(n => n.Id == id.Value).FirstOrDefaultAsync();

            if (course != null)
            {

                return View("ViewCourse", course);
            }
            else
            {
                return BadRequest("课程不存在");
            }


        }





    }


    public class CourseData
    {
        public Data.Entities.Course Course { get; set; }

        public List<Data.Entities.Lesson> Lessons { get; set; } = new List<Data.Entities.Lesson>();

    }
}
